#include "SWFMasterWindow.h"
#include "ui_SWFMasterWindow.h"
#include <QFileDialog>
#include <thread>
#include "swf/Object.h"
#include "swf/SWFDecoder.h"
#include "swf/SWFEncoder.h"
#include "swf/abc/AS3Model.h"
#include "editor/Icon.h"
#include "editor/EditorContainer.h"
#include "editor/model/SWFTreeModel.h"
#include "editor/SelectExternalTagWindow.h"

SWFMasterWindow::SWFMasterWindow(QWidget *parent)
	: QMainWindow(parent)
	, ui(new Ui::SWFMasterWindow)
	, _as3swf(nullptr)
{
    ui->setupUi(this);

    _swfObjectModel = new SWFTreeModel();

    ui->itemTree->setModel(_swfObjectModel);
	ui->itemTree->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
	_editorContainer = new EditorContainer();
	ui->horizontalLayout_2->addWidget(_editorContainer);

	this->startTimer(1000);
}

SWFMasterWindow::~SWFMasterWindow()
{
    delete ui;
}

void SWFMasterWindow::onOpen()
{
	if (_as3swf != nullptr)
		return;//TODO: message box

	QString fileName = QFileDialog::getOpenFileName(this, "Select SWF", "", "SWF(*.swf)");
	if (!QFile::exists(fileName))
		return;//TODO: message box
	
	DecodeSWFProgressDialog d(fileName);
	SWF* swf = (SWF*) d.exec();
	
	_as3swf = new AS3SWF(swf, QFileInfo(fileName));
	SWFItem* item = new SWFItem(_as3swf);
	_swfObjectModel->appendRow(item);
}

void SWFMasterWindow::onSaveAs()
{
	QString fileName = QFileDialog::getSaveFileName(this, "Save SWF", "", "SWF(*.swf)");
	if (fileName.isEmpty() == false)
	{
		SWFEncoder encoder;
		SWF* swf = _as3swf->convertToSWF();
		encoder.save(swf, fileName.toStdString());
	}
}

void SWFMasterWindow::onItemTreeContextMenuRequested( const QPoint& pos )
{
	auto index = ui->itemTree->currentIndex();
	auto item = _swfObjectModel->itemFromIndex(index);
	QMenu* menu = item->requestContextMenu();
	if (menu != nullptr)
	{
		menu->exec(QCursor::pos());
	}
}

void SWFMasterWindow::onItemTreeSelectItem( const QModelIndex& index )
{
	auto model = _swfObjectModel->itemFromIndex(index);
	if (model)
	{
		_editorContainer->openEditor(model);
	}
}

void SWFMasterWindow::onAbout()
{

}

void SWFMasterWindow::onReplaceTag()
{
	auto index = ui->itemTree->currentIndex();
	auto item = _swfObjectModel->itemFromIndex(index);
	if (item)
	{
		SelectExternalTagWindow* win = new SelectExternalTagWindow();
		int result = win->exec();
		SWFTag* tag = (SWFTag*) result;
		if (tag)
		{
			SWFTagWrapper* w = (SWFTagWrapper*) item->getUserData();
			w->replace(tag);
		}
	}
}

void SWFMasterWindow::timerEvent(QTimerEvent *)
{
	AutoreleasePool::getInstance()->check();
}

DecodeSWFProgressDialog::DecodeSWFProgressDialog( const QString& name )
	: _swf(nullptr)
{
	AutoreleasePool::getInstance()->pause(true);
	std::thread t(std::bind(&DecodeSWFProgressDialog::decode, this, name));
	t.detach();
	this->startTimer(50);
	this->setCancelButton(nullptr);

	int type = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::CustomizeWindowHint;
	type &= ~Qt::WindowCloseButtonHint;
	this->setWindowFlags((Qt::WindowFlags) type);
}

int DecodeSWFProgressDialog::exec()
{
	QProgressDialog::exec();
	while (_swf == nullptr);
	AutoreleasePool::getInstance()->pause(false);
	return (int)_swf;
}

void DecodeSWFProgressDialog::timerEvent( QTimerEvent * )
{
	this->setValue(_decoder.getProgress() * 100);
	if (_decoder.getProgress() == 1)
		this->done((int) _swf);
}

void DecodeSWFProgressDialog::decode( const QString& name )
{
	_swf = _decoder.decode(name.toStdString());
	_swf->retain();
}

DecodeSWFProgressDialog::~DecodeSWFProgressDialog()
{

}
